package org.dromara.system.service.impl;

import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.system.domain.YzlScheduleTask;
import org.dromara.system.domain.bo.YzlScheduleTaskBo;
import org.dromara.system.domain.vo.ScheduleGanttQueryVo;
import org.dromara.system.domain.vo.YzlScheduleTaskVo;
import org.dromara.system.mapper.YzlScheduleTaskMapper;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.YzlScheduleFormationBo;
import org.dromara.system.domain.vo.YzlScheduleFormationVo;
import org.dromara.system.domain.YzlScheduleFormation;
import org.dromara.system.mapper.YzlScheduleFormationMapper;
import org.dromara.system.service.IYzlScheduleFormationService;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 计划编制Service业务层处理
 *
 * @author wfy
 * @date 2025-09-15
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class YzlScheduleFormationServiceImpl implements IYzlScheduleFormationService {

    private final YzlScheduleFormationMapper baseMapper;

    private final YzlScheduleTaskMapper taskMapper;

    /**
     * 查询计划编制
     *
     * @param id 主键
     * @return 计划编制
     */
    @Override
    public YzlScheduleFormationVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询计划编制列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 计划编制分页列表
     */
    @Override
    public TableDataInfo<YzlScheduleFormationVo> queryPageList(YzlScheduleFormationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<YzlScheduleFormation> lqw = buildQueryWrapper(bo);
        Page<YzlScheduleFormationVo> result = baseMapper.selectVoPageDept(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的计划编制列表
     *
     * @param bo 查询条件
     * @return 计划编制列表
     */
    @Override
    public List<YzlScheduleFormationVo> queryList(YzlScheduleFormationBo bo) {
        LambdaQueryWrapper<YzlScheduleFormation> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoListDept(lqw);
    }

    private LambdaQueryWrapper<YzlScheduleFormation> buildQueryWrapper(YzlScheduleFormationBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<YzlScheduleFormation> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(YzlScheduleFormation::getId);
        lqw.eq(bo.getDeptId() != null, YzlScheduleFormation::getDeptId, bo.getDeptId());
        lqw.eq(bo.getUserId() != null, YzlScheduleFormation::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), YzlScheduleFormation::getRemarks, bo.getRemarks());
        lqw.like(StringUtils.isNotBlank(bo.getProjectName()), YzlScheduleFormation::getProjectName, bo.getProjectName());
        lqw.like(StringUtils.isNotBlank(bo.getPlanName()), YzlScheduleFormation::getPlanName, bo.getPlanName());
        lqw.eq(bo.getPlanDate() != null, YzlScheduleFormation::getPlanDate, bo.getPlanDate());
        lqw.eq(StringUtils.isNotBlank(bo.getMasterPlan()), YzlScheduleFormation::getMasterPlan, bo.getMasterPlan());
        lqw.eq(StringUtils.isNotBlank(bo.getFormationFiles()), YzlScheduleFormation::getFormationFiles, bo.getFormationFiles());
        lqw.eq(StringUtils.isNotBlank(bo.getFormationStatus()), YzlScheduleFormation::getFormationStatus, bo.getFormationStatus());
        lqw.eq(bo.getStartDate() != null, YzlScheduleFormation::getStartDate, bo.getStartDate());
        lqw.eq(bo.getEndDate() != null, YzlScheduleFormation::getEndDate, bo.getEndDate());
        lqw.between(params.get("beginCompletion") != null && params.get("endCompletion") != null,
            YzlScheduleFormation::getCompletion ,params.get("beginCompletion"), params.get("endCompletion"));
        return lqw;
    }

    private LambdaQueryWrapper<YzlScheduleTask> buildQueryWrapperTask(YzlScheduleTaskBo bo) {
        LambdaQueryWrapper<YzlScheduleTask> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(YzlScheduleTask::getId);
        lqw.eq(bo.getDeptId() != null, YzlScheduleTask::getDeptId, bo.getDeptId());
        /*lqw.eq(bo.getUserId() != null, YzlScheduleTask::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), YzlScheduleTask::getRemarks, bo.getRemarks());*/
        lqw.eq(bo.getFormationId() != null, YzlScheduleTask::getFormationId, bo.getFormationId());
        return lqw;
    }

    /**
     * 新增计划编制
     *
     * @param bo 计划编制
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(YzlScheduleFormationBo bo) {
        YzlScheduleFormation add = MapstructUtils.convert(bo, YzlScheduleFormation.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改计划编制
     *
     * @param bo 计划编制
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(YzlScheduleFormationBo bo) {
        YzlScheduleFormation update = MapstructUtils.convert(bo, YzlScheduleFormation.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(YzlScheduleFormation entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除计划编制信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public List<ScheduleGanttQueryVo> ganttInfo(YzlScheduleFormationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<YzlScheduleFormation> lqw = buildQueryWrapper(bo);
        Page<YzlScheduleFormationVo> result = baseMapper.selectVoPageDept(pageQuery.build(), lqw);
        List<ScheduleGanttQueryVo> ganttQueryList = new ArrayList<>();
        for (YzlScheduleFormationVo kmap : result.getRecords()) {
            ScheduleGanttQueryVo scheduleGanttQuery = new ScheduleGanttQueryVo();
            scheduleGanttQuery.setId(kmap.getId());
            scheduleGanttQuery.setText(kmap.getProjectName());
            String startDate = new SimpleDateFormat("yyyy-MM-dd").format(kmap.getStartDate());
            String endDate = new SimpleDateFormat("yyyy-MM-dd").format(kmap.getEndDate());
            scheduleGanttQuery.setStart_date(startDate);
            scheduleGanttQuery.setDuration(getIntervalDays(startDate, endDate));
            scheduleGanttQuery.setOpen(false);
            scheduleGanttQuery.setToolTipsTxt(kmap.getPlanName());
            scheduleGanttQuery.setProgress((double) (kmap.getCompletion()==null?0:   (kmap.getCompletion() / 100)));
            scheduleGanttQuery.setStatus("parent");
            scheduleGanttQuery.setFormationStatus(kmap.getFormationStatus());
            ganttQueryList.add(scheduleGanttQuery);

            YzlScheduleTaskBo taskBo =new YzlScheduleTaskBo();
            taskBo.setFormationId(kmap.getId());
            taskBo.setDeptId(kmap.getDeptId());
            LambdaQueryWrapper<YzlScheduleTask> lqwTask = buildQueryWrapperTask(taskBo);
            List<YzlScheduleTaskVo> list = taskMapper.selectVoListDept(lqwTask);
            for (int i = 0; i < list.size(); i++) {
                ScheduleGanttQueryVo ganttQuery = new ScheduleGanttQueryVo();
                ganttQuery.setId(list.get(i).getId());
                ganttQuery.setText(list.get(i).getTaskName());
                ganttQuery.setToolTipsTxt(list.get(i).getTaskName()+1);
                String start = new SimpleDateFormat("yyyy-MM-dd").format(list.get(i).getStartTime());
                String end = new SimpleDateFormat("yyyy-MM-dd").format(list.get(i).getEndTime());
                ganttQuery.setStart_date(start);
                ganttQuery.setDuration(getIntervalDays(start, end));
                ganttQuery.setParent(list.get(i).getParentId()==null?kmap.getId():list.get(i).getParentId());
                ganttQuery.setTaskId(list.get(i).getId());
                ganttQuery.setType(new Random().nextInt(4 + 1) + 1);//1到4随机数
                ganttQuery.setProgress(Double.valueOf(list.get(i).getCompletionPercentage()) / 100);
                if (ganttQuery.getType() == 1) {
                    ganttQuery.setStatus("yellow");
                } else if (ganttQuery.getType() == 2) {
                    ganttQuery.setStatus("pink");
                } else if (ganttQuery.getType() == 3) {
                    ganttQuery.setStatus("green");
                } else if (ganttQuery.getType() == 4) {
                    ganttQuery.setStatus("popular");
                }
                ganttQueryList.add(ganttQuery);
            }
        }
        return ganttQueryList;
    }


    /**
     * 利用SimpleDateFormat类计算两个时间的天数间隔
     * @throws ParseException
     */
    public Integer getIntervalDays(String start, String end) {
        // 日期格式化
        DateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = null;
        try {
            startDate = simpleFormat.parse(start);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Date endDate = null;
        try {
            endDate = simpleFormat.parse(end);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        long startTime = startDate.getTime();
        long endTime = endDate.getTime();
        int days = (int) ((endTime - startTime) / (1000 * 60 * 60 * 24));
        return days+1;
    }
}
